package frontend_package;

import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;

import backend_package.Packet;

/**
 * Assigns listeners to Analyst panel buttons. This class has a listener classes
 * for the Analyst panel actions
 * 
 * @author Syrym
 * 
 */
public class Listeners extends Observable implements Observer {
	/** String file path */
	private String dbfilesPath = "";
	/** which table index */
	private Integer whichTable;
	/** username String */
	private String username;
	/** selected columns of draft and rfp table */
	private int[] selectedColumnsRFPdraft;
	/** selected row of rfp and draft table */
	private int selectedRowRFPdraft;
	/** selected rows of assigned rfp table */
	private int[] selectedRowsAssignedRFPs;
	/** assigned rfp table paths */
	private String pathAssignedRFPs[][];
	/** rfp and draft table paths */
	private String pathRFPdrafts[][];

	/**
	 * Constructor
	 * 
	 * @author Syrym
	 */
	public Listeners() {
		selectedRowsAssignedRFPs = null;
		dbfilesPath = reverseToFWDSlashes(System.getProperty("java.io.tmpdir"))+ "dbfiles"; 

	}
	/**Helper method to convert back slashes to 
	 * forward slashes.
	 * @author Syrym
	 * */
	private String reverseToFWDSlashes(String path) {

		while (path.indexOf('\\') > -1) {
			int BSlashInd = path.indexOf('\\');
			path = path.substring(0, BSlashInd) + "/"
					+ path.substring(++BSlashInd);
		}
		return path;
	}
	/**
	 * Listener for Assigned Table
	 * 
	 * @author Syrym
	 * 
	 */
	class AssignedTableListListener implements ListSelectionListener {

		@Override
		public void valueChanged(ListSelectionEvent e) {
			setChanged();
			notifyObservers(new Packet("lis_selectedrows_assigned_ap"));
		}

	}

	/**
	 * Listeners for Assigned RFP Table
	 * 
	 * @author Syrym
	 * 
	 */
	class DraftTableListListener implements ListSelectionListener {

		@Override
		public void valueChanged(ListSelectionEvent e) {
			setChanged();
			notifyObservers(new Packet("lis_selectedrows_draftrfp_ap"));
		}

	}

	/**
	 * Listener for Draft Table Column
	 * 
	 * @author Syrym
	 * 
	 */
	class DraftTableColumnListener implements TableColumnModelListener {
		@Override
		public void columnSelectionChanged(ListSelectionEvent e) {
			setChanged();
			notifyObservers(new Packet("lis_selectedcols_draftrfp_ap"));
		}

		@Override
		public void columnAdded(TableColumnModelEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void columnRemoved(TableColumnModelEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void columnMoved(TableColumnModelEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void columnMarginChanged(ChangeEvent e) {
			// TODO Auto-generated method stub

		}
	}

	/**
	 * Open File listener
	 * 
	 * @author Syrym
	 * 
	 */
	class OpenFileListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			setChanged();
			notifyObservers(new Packet("lis_openfile_ap"));

			if (whichTable != null && whichTable == 0) {
				for (int i = 0; i < selectedColumnsRFPdraft.length; i++) {
					open((String) pathRFPdrafts[selectedRowRFPdraft][selectedColumnsRFPdraft[i]]);
				}
			} else if (whichTable != null && whichTable == 1) {
				for (int i = 0; i < selectedRowsAssignedRFPs.length; i++) {
					open((String) pathAssignedRFPs[selectedRowsAssignedRFPs[i]][0]);
				}
			} else {
				JOptionPane.showMessageDialog(null,
						"No RFP/Draft file(s) selected!");
			}

		}

		/**
		 * Opens file from its given file path
		 * 
		 * @author Kylar
		 * 
		 */
		private void open(String filepath) {
			File file = new File(filepath);
			try {
				Desktop.getDesktop().open(file);
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

	/**
	 * New Draft listener
	 * 
	 * @author Syrym
	 * 
	 */
	class NewDraftListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			setChanged();
			notifyObservers(new Packet("lis_newdraft_ap"));

			if (whichTable != null && whichTable == 1
					&& selectedRowsAssignedRFPs != null) {
				String rfppath = pathAssignedRFPs[selectedRowsAssignedRFPs[0]][0];
				String rfp = getFileName(rfppath);
				String newDraftPath = dbfilesPath + "/" + username + "/" + rfp
						+ "draft.docx";
				putToDraftsTable(newDraftPath, rfppath);
				removeRFPfromAssignedTable(rfppath);
				try {
					FileOutputStream outStream = new FileOutputStream(
							newDraftPath);// make file
					outStream.close();
					File file = new File(newDraftPath);
					Desktop.getDesktop().open(file);// open file
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				} catch (IOException e2) {
					e2.printStackTrace();
				}
				Object[] oarr1 = { pathAssignedRFPs, pathRFPdrafts };
				setChanged();
				notifyObservers(new Packet("lis_updateddata_ap", oarr1,
						username));
				Object[] oarr2 = { rfppath, newDraftPath };
				setChanged();
				notifyObservers(new Packet("lis_updatedata_db", oarr2, username));
			} else {
				JOptionPane.showMessageDialog(null,
						"No Assigned RFP is selected!");
			}

		}

		/**
		 * Returns file name
		 * 
		 * @author Syrym
		 * @param rfppath
		 * @return file name
		 */
		private String getFileName(String rfppath) {
			int lastBSlash_0 = rfppath.lastIndexOf('/');
			int length_0 = rfppath.length();
			rfppath = rfppath.substring(++lastBSlash_0, length_0);
			int lastdot = rfppath.lastIndexOf('.');
			return rfppath.substring(0, lastdot);
		}

		/**
		 * Puts files into draft tables
		 * 
		 * @author Syrym
		 * @param newDraftPath
		 * @param rfppath
		 */
		private void putToDraftsTable(String newDraftPath, String rfppath) {
			String[][] newPathRFPDrafts = new String[pathRFPdrafts.length + 1][2];
			for (int i = 0; i < pathRFPdrafts.length; i++) {
				newPathRFPDrafts[i][0] = pathRFPdrafts[i][0];
				newPathRFPDrafts[i][1] = pathRFPdrafts[i][1];
			}
			newPathRFPDrafts[pathRFPdrafts.length][0] = pathAssignedRFPs[selectedRowsAssignedRFPs[0]][0];
			newPathRFPDrafts[pathRFPdrafts.length][1] = newDraftPath;
			pathRFPdrafts = newPathRFPDrafts;
		}

		/**
		 * Removes RFP from Assigned table, when analyst starts working on it
		 * 
		 * @author Syrym
		 * @param rfppath
		 */
		private void removeRFPfromAssignedTable(String rfppath) {
			String[][] newPathAssignedRFPs = new String[pathAssignedRFPs.length - 1][0];
			int selectedIndex = selectedRowsAssignedRFPs[0];
			for (int i = 0; i < newPathAssignedRFPs.length; i++) {
				if (i != selectedIndex) {
					newPathAssignedRFPs[i][0] = pathAssignedRFPs[i][0];
				} else {
					newPathAssignedRFPs[i][0] = pathAssignedRFPs[i + 1][0];
				}
			}
			pathAssignedRFPs = newPathAssignedRFPs;
		}
	}

	/**
	 * Log out listener
	 * 
	 * @author Syrym
	 * 
	 */
	class LogoutListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			setChanged();
			notifyObservers(new Packet("ap_logoutuserpanel")); // notifies
																// Mainframe
		}
	}

	/**
	 * Action for new draft button
	 * 
	 * @author Syrym
	 * @param packet
	 */
	public void prepareNewDraftActionData(Packet packet) {
		if (packet.get(0) != null && packet.get(1) != null
				&& packet.get(2) != null && packet.get(3) != null) {
			pathRFPdrafts = (String[][]) packet.get(0);
			pathAssignedRFPs = (String[][]) packet.get(1);
			whichTable = (int) packet.get(2);
			selectedRowsAssignedRFPs = (int[]) packet.get(3);
			username = packet.getUsername();
		}
	}

	/**
	 * Open button listener
	 * 
	 * @author Syrym
	 * @param packet
	 */
	public void prepareOpenFileActionData(Packet packet) {
		if (packet.get(0) != null
				&& packet.get(1) != null
				&& packet.get(2) != null
				&& (packet.get(3) != null || (packet.get(4) != null && packet
						.get(5) != null))) {
			pathRFPdrafts = (String[][]) packet.get(0);
			pathAssignedRFPs = (String[][]) packet.get(1);
			whichTable = (int) packet.get(2);
			selectedRowsAssignedRFPs = (int[]) packet.get(3);
			selectedColumnsRFPdraft = (int[]) packet.get(4);
			selectedRowRFPdraft = (int) packet.get(5);
			username = packet.getUsername();
		}
	}

	@Override
	public void update(Observable o, Object arg) {
		Packet packet = (Packet) arg;
		if (o instanceof AnalystPanel
				&& packet.getTag().equals("ap_selectedcols_draftrfp_lis")) {
			selectedColumnsRFPdraft = (int[]) packet.get(0);
		} else if (o instanceof AnalystPanel
				&& packet.getTag().equals("ap_newdraft_lis")) {
			prepareNewDraftActionData(packet);
		} else if (o instanceof AnalystPanel
				&& packet.getTag().equals("ap_openfile_lis")) {
			prepareOpenFileActionData(packet);
		}

	}
}
